﻿using System.Collections.ObjectModel;

namespace Central.Linq {

	/// <summary>
	/// Класс определения поля в запросе
	/// </summary>
	public class FieldDefinition {
		#region конструктор

		/// <summary>
		/// Конструктор
		/// </summary>
		public FieldDefinition() {
		}

		/// <summary>
		/// Конструктор
		/// </summary>
		public FieldDefinition(string name) {
			this.Name = name;
		}

		/// <summary>
		/// Конструктор
		/// </summary>
		public FieldDefinition(string expression, string name) {
			this.Name = name;
			this.Expression = expression;
		}

		#endregion конструктор

		/// <summary>
		/// Наименование поля
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// Выражение для определения поля
		/// </summary>
		public string Expression { get; set; }

		/// <summary>
		/// Коллекция значений в выражении
		/// </summary>
		public Collection<object> Values { get; private set; }

		#region [+] cвойства

		/// <summary>
		/// возвращаемый предикат фильтров
		/// </summary>
		public SelectPredicate Predicate {
			get {
				return this.GeneratePredicate();
			}
		}

		#endregion [+] cвойства

		#region скрытые методы

		private SelectPredicate GeneratePredicate() {
			return new SelectPredicate(string.IsNullOrEmpty(this.Expression) ? this.Name : System.String.Concat(this.Expression, " AS ", this.Name), this.Values);
		}

		#endregion скрытые методы

		#region методы

		/// <summary>
		/// сравнение объектов
		/// </summary>
		/// <returns></returns>
		public override bool Equals(object obj) {
			return Equals(obj as FieldDefinition);
		}

		/// <summary>
		/// сравнение объектов FieldDefinition
		/// </summary>
		/// <param name="other"></param>
		/// <returns></returns>
		public bool Equals(FieldDefinition other) {
			if (other == null)
				return false;
			return (other.Name.Equals(this.Name) && other.Expression.Equals(this.Expression));
		}

		/// <summary>
		/// получение Hash кода объекта FieldDefinition
		/// </summary>
		/// <returns></returns>
		public override int GetHashCode() {
			//Calculate the hash code
			return this.Name.GetHashCode() ^ this.Expression.GetHashCode();
		}

		/// <summary>
		/// Метод добавления expressionValue в коллекцию
		/// </summary>
		/// <param name="expressionValue">значение в выражении</param>
		public void Add(object expressionValue) {
			if (expressionValue == null)
				return;

			if (this.Values == null)
				this.Values = new Collection<object>();

			if (!this.Values.Contains(expressionValue))
				this.Values.Add(expressionValue);
		}

		/// <summary>
		/// Метод удаления expressionValue из коллекции
		/// </summary>
		/// <param name="expressionValue"></param>
		public void Remove(object expressionValue) {
			if (expressionValue == null)
				return;

			if (this.Values != null)
				this.Values.Remove(expressionValue);
		}

		/// <summary>
		/// Метод очищения коллекции ExpressionValues
		/// </summary>
		public void Clear() {
			if (this.Values != null)
				this.Values.Clear();
		}

		#endregion методы
	}
}